package com.tengniu.framework.interceptor;

import com.alibaba.fastjson.JSON;
import com.tengniu.biz.bo.LoginResultBO;
import com.tengniu.api.common.CurrentUser;
import com.tengniu.api.enums.StateCode;
import com.tengniu.common.annotation.Token;
import com.tengniu.common.core.domain.AjaxResult;
import com.tengniu.common.core.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;

/**
 * @author 林明谦
 * @version 1.0
 * @date 2021/7/3 22:36
 */
@Order(1)
@Slf4j
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private RedisCache redisCache;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>　H5登录鉴权拦截器．．．");
        if (handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod)handler;
            Method method = handlerMethod.getMethod();
            Token loginType = method.getAnnotation(Token.class);
            if (Objects.isNull(loginType)){
                return true;
            }else {
                boolean isLogin = loginType.login();
                String token = request.getHeader("token");
                String timestamp = request.getHeader("timestamp");
//                if (StringUtils.isBlank(timestamp)){
//                    //时间戳为空
//                    out(response, StateCode.B10003);
//                    return false;
//                }
//                if ((System.currentTimeMillis() - Long.valueOf(timestamp) < 1000*60*5) && !"dev".equals(SpringUtils.getActiveProfile())){
//                    //时间戳检验失败
//                    out(response, StateCode.B10004);
//                    return false;
//                }
                if ((isLogin && StringUtils.isBlank(token))){
                    //需要登陆的时候，token为空
                    out(response, StateCode.B10002);
                    return false;
                }
                //获取token
                LoginResultBO loginResultBO = null;
                if (StringUtils.isNoneBlank(token)){
                    loginResultBO = redisCache.getCacheObject(token);
                }
                if (Objects.nonNull(loginResultBO)){
                    //刷新token
                    CurrentUser.REDIS_USER.set(loginResultBO);
                }
                if (!isLogin){
                    //不需要登录 直接返回通过
                    return true;
                }
                if (Objects.isNull(loginResultBO)){
                    //token过期...
                    out(response, StateCode.B10002);
                    return false;
                }
                int[] roles = loginType.companyType();
                if (Objects.isNull(roles) || roles.length == 0){
                    //登录角色没有设置
                    out(response, StateCode.P00001);
                    return false;
                }
                LoginResultBO finalLoginResultBO = loginResultBO;
                boolean isHave = Arrays.stream(roles).anyMatch(role -> role == finalLoginResultBO.getCompanyType());
                if (!isHave){
                    //登录角色没有设置
                    out(response, StateCode.B10007);
                    return false;
                }
            }
        }
        return true;
    }

    /**
     *  输出
     * @param response
     * @param stateCode
     * @throws IOException
     */
    private void out(HttpServletResponse response, StateCode stateCode) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        AjaxResult result = AjaxResult.unauthorized(stateCode.getMsg());
        response.getWriter().append(JSON.toJSONString(result));
    }
}
